require 'test/unit'
require 'database/database'

require 'models/entity'
class DatabaseTest < Test::Unit::TestCase
    def setup
        @one = Entity.new; @one.name="one"
        @two = Entity.new; @two.name="Two"
        @three = Entity.new; @three.name="th r ee"

        @v_names = VectorDatabase.new
        @one=@v_names.add(@one)
        @two=@v_names.add(@two)
        @three=@v_names.add(@three)
        @v = [@one,@two,@three]

        @mone = Entity.new; @mone.name="one"
        @mtwo = Entity.new; @mtwo.name="Two"
        @mthree = Entity.new; @mthree.name="th r ee"

        @m_names = MapDatabase.new
        @mone = @m_names.add(@mone)
        @mtwo = @m_names.add(@mtwo)
        @mthree = @m_names.add(@mthree)
        @m = { @mone.oid => @mone,
            @mtwo.oid => @mtwo,
            @mthree.oid => @mthree }
    end
    def test_vector_db
        ad = VectorDatabase.new
        assert_equal(0,ad.size)
        
        ad.add(@one)
        assert_equal(1,ad.size)
    end
    def test_map_db
        md = MapDatabase.new
        assert_equal(0,md.size)
        md.add(@one)
        assert_equal(1,md.size)
    end
    def test_vector_access
        v = VectorDatabase.new
        one = Entity.new; one.name="One"
        two = Entity.new; two.name="two"
        one = v.add(one)
        two = v.add(two)

        assert_equal(2, v.size)
        assert_equal(v.get(one.oid).name,one.name)
        assert_equal(v.get(two.oid).name,two.name)
    end
    def test_map_access
        v = MapDatabase.new
        one = Entity.new; one.name="One"
        two = Entity.new; two.name="two"
        one = v.add(one)
        two = v.add(two)

        assert_equal(2, v.size)
        assert_equal(v.get(one.oid).name,one.name)
        assert_equal(v.get(two.oid).name,two.name)
    end
    def test_vector_enumerable
        empty = []
        @v_names.each do |element|
            empty << element
        end
        assert_equal(@v,empty)
    end
    def test_map_enumerable
        empty = {}
        @m_names.each do |element|
            empty[element.oid] = element
        end
        assert_equal(@m,empty)
    end
    def test_vector_searchable
        named_two = @v_names.find_by_name('two')
        assert_not_nil(named_two)
        assert_equal(named_two.name,@two.name)
    end
    def test_map_searchable
        named_two = @m_names.find_by_name('two')
        assert_not_nil(named_two)
        assert_equal(named_two.name,@two.name)
    end
    def test_vector_next_id
        v = VectorDatabase.new
        one = Entity.new
        assert_nil(one.oid)
        one = v.add(one)
        assert_not_nil(one.oid)

        two = Entity.new
        two = v.add(two)
        assert_not_nil(two.oid)
        assert_not_equal(one.oid,two.oid)
    end
    def test_map_next_id
        v = MapDatabase.new
        one = Entity.new
        assert_nil(one.oid)
        one = v.add(one)
        assert_not_nil(one.oid)

        two = Entity.new
        two = v.add(two)
        assert_not_nil(two.oid)
        assert_not_equal(one.oid,two.oid)
    end
end
class TemplateBasedEntity < Entity
    properties :template
end
class TemplateEntity < Entity
    def create_instance
        inst = TemplateBasedEntity.new
        inst.name = 'Instance of Template'
        inst.template = self
        inst
    end
end

class TemplateInstanceDatabaseTest < Test::Unit::TestCase
    def setup
        @ti = TemplateInstanceDatabase.new

        # for testing only
        class << @ti
            def tc_add_template(t)
                @templates.add(t)
            end
        end
        @tmpl = TemplateEntity.new
        @tmpl.oid = 1
        @tmpl.name = "Template"
    end
    def test_enumerable
        @ti.each do |t|
            assert_not_nil(t)
        end
    end
    def test_search_for_template
        assert_nil(@ti.find_template_by_name('missing'))

        @ti.tc_add_template(@tmpl) # testing only
        assert_not_nil(@ti.find_template_by_name(@tmpl.name))
    end

    def test_generate
        @ti.tc_add_template(@tmpl)

        t = @ti.find_template_by_name('template')
        i = @ti.generate_from_template(t)

        assert_not_nil(i.oid)
        assert(i.oid > 0)
        assert_equal("Instance of Template",i.name)

        i2 = @ti.generate_from_template(t)
        assert_not_equal(i.oid,i2.oid)
        assert_not_nil(i2.oid)
        assert(i2.oid > 0)
        assert_equal("Instance of Template",i2.name)
    end
    def test_copy
        @ti.tc_add_template(@tmpl)

        i = @ti.generate_from_template(@tmpl)
        c = @ti.generate_copy(i)

        assert_not_nil(c)
        assert_equal(i.name,c.name)
        assert_not_equal(i.oid,c.oid)
    end

end
